/**
 * 
 */
package com.nari.baseinfo.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.nari.baseinfo.model.IShareArea;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng
 * @date 2013-8-1
 */
public class ShareAreaDaoImpl extends GenericDaoImpl<IShareArea, String> implements IShareAreaDao {
	private IResourceAccessControlDao iResourceAccessControlDao;
	
	/**
	 * 分页查询分摊域信息
	 * @param areaName  分摊域名称(可选)
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-26
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IShareArea> queryShareAreaWithPagecond(String areaName, 
			String projectUID, String communityUID, PageCond pageCond) throws Exception {
		Criteria listCriteria = this.getCurrentSession().createCriteria(IShareArea.class);
		Criteria countCriteria = this.getCurrentSession().createCriteria(IShareArea.class);
		//分摊域名称
		if(areaName!=null && !"".equals(areaName.trim())) {
			listCriteria.add(Restrictions.ilike("areaName", areaName.trim().toLowerCase(), MatchMode.ANYWHERE));
			countCriteria.add(Restrictions.ilike("areaName", areaName.trim().toLowerCase(), MatchMode.ANYWHERE));
		}
		
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			countCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			countCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
		if(!"".equals(authorityRes)) {
			//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
			listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			countCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
		}
		//统计结果集个数
		int total = ((Long)countCriteria.setProjection(Projections.rowCount()).list().get(0)).intValue();
		//结果集排序
		listCriteria.addOrder(Order.asc("areaName"));
		//结果集分页
		listCriteria.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IShareArea> shareAreaPage = new ResultWithPageCond<IShareArea>();
		shareAreaPage.setList(listCriteria.list());
		shareAreaPage.setPageCond(pageCond);
		return shareAreaPage;
	}
	
	/**
	 * 根据分摊域所属信息(所属项目、所属小区)查询其所属的分摊域列表
	 * @param projectUID
	 * @param communityUID
	 * @return 若所属项目，所属小区均不存在，则返回空列表
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-26
	 */
	@SuppressWarnings("unchecked")
	public List<IShareArea> queryShareAreaByBelongings(String projectUID, 
			String communityUID) throws Exception {
		if((projectUID!=null && !"".equals(projectUID)) 
				|| (communityUID!=null && !"".equals(communityUID))) {
			Criteria listCriteria = this.getCurrentSession().createCriteria(IShareArea.class);
			//所属项目
			if(projectUID!=null && !"".equals(projectUID.trim())) {
				listCriteria.add(Restrictions.eq("projectID", projectUID.trim()));
			}
			//所属小区
			if(communityUID!=null && !"".equals(communityUID.trim())) {
				listCriteria.add(Restrictions.eq("communityID", communityUID.trim()));
			}
			//权限资源匹配
			String authorityRes = iResourceAccessControlDao.queryAuthorityProjResSql();
			if(!"".equals(authorityRes)) {
				//这是一个直接与底层数据库耦合的查询，注意避免数模更改带来的系统问题
				listCriteria.add(Restrictions.sqlRestriction("{alias}.t_project_id in("+authorityRes+")"));
			}
			//结果集排序
			listCriteria.addOrder(Order.asc("areaName"));
			return listCriteria.list();
		}
		return new ArrayList<IShareArea>();
	}
	
	/**
	 * 通过唯一标识列表查询分摊域信息
	 * @param idList 唯一标识列表，若为空列表，则结果集返回空
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-9
	 */
	public List<IShareArea> queryShareAreaByIDList(List<String> idList) throws Exception {
		if(idList!=null && idList.size()>0) {
			StringBuffer queryHQL = new StringBuffer("select distinct sa from IShareArea sa ");
			queryHQL.append("where sa.id in(");
			for(int index=0; index<idList.size(); index++) {
				queryHQL.append("'");
				queryHQL.append(idList.get(index));
				queryHQL.append("'");
				if(index < idList.size()-1) {
					queryHQL.append(",");
				}
			}
			queryHQL.append(") ");
			queryHQL.append("order by sa.areaName");
			return this.runQueryHSql(queryHQL.toString());
		}
		return null;
	}
	
	/**
	 * 通过唯一标识列表查询分摊域id-areaName映射信息
	 * @param idList 唯一标识列表，若为空列表，则空映射
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-9
	 */
	public Map<String, String> queryIdNameMapByIDList(List<String> idList) throws Exception {
		//查询分摊域id-areaName列表
		List<Object> shareAreaAttrs = null;
		if(idList!=null && idList.size()>0) {
			StringBuffer queryHQL = new StringBuffer("select distinct sa.id,sa.areaName ");
			queryHQL.append("from IShareArea sa ");
			queryHQL.append("where sa.id in(");
			for(int index=0; index<idList.size(); index++) {
				queryHQL.append("'");
				queryHQL.append(idList.get(index));
				queryHQL.append("'");
				if(index < idList.size()-1) {
					queryHQL.append(",");
				}
			}
			queryHQL.append(") ");
			queryHQL.append("order by sa.areaName");
			shareAreaAttrs = this.runQueryHSqlObject(queryHQL.toString());
		}
		//格式化id-areaName映射关系
		Map<String, String> shareAreaMap = new HashMap<String, String>();
		if(shareAreaAttrs!=null && shareAreaAttrs.size()>0) {
			for(Object attrs: shareAreaAttrs) {
				Object[] attrArray = (Object[]) attrs;
				shareAreaMap.put((String)attrArray[0], (String)attrArray[1]);
			}
		}
		return shareAreaMap;
	}
	
	/**
	 * 查询系统分摊域列表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-9
	 */
	public List<IShareArea> queryAllShareArea() throws Exception {
		String hsql = "select sa from IShareArea sa";
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			hsql += " and sa.projectID in("+authorityRes+")";
		}
		hsql += " order by sa.areaName";
		return this.runQueryHSql(hsql);
	}
	
	/**
	 * 根据分摊域ID级联删除关联信息
	 * 包括：热用户、系统用户及角色、热量表、分配表、散热器、
	 * 分摊域、分摊域分摊账单、用户分摊账单
	 * 注意：热量表数据、分配表数据等表计数据具有不可恢复性，因此不能作为级联删除的对象
	 * @param areaUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-20
	 */
	public ResponseMsg deleteCascadeByAreaUID(String areaUID) throws Exception {
		//删除分摊域所属散热器
		String delSinkerHql = "delete from PSinkInfo sink " +
				"where sink.roomId in(select hr.id " +
									"from IHeatRoom hr " +
									"where hr.shareAreaID='"+areaUID+"')";
		this.runFormatHSql(delSinkerHql);
		//删除分摊域所属分配表
		String delAssignMeterHql = "delete from IAssignMeter am " +
				"where am.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.shareAreaID='"+areaUID+"')";
		this.runFormatHSql(delAssignMeterHql);
		//删除分摊域所属热量表
		String delHeatMeterHql = "delete from IHeatMeter hm " +
				"where hm.shareAreaID='"+areaUID+"')";
		this.runFormatHSql(delHeatMeterHql);
		//删除分摊域所属分摊账单
		String delSinkResultHql = "delete from IShareSinkResult ssr " +
				"where ssr.userShareResultID in(select usr.id " +
											"from IUserShareResult usr " +
											"where usr.areaResultID in(select sar.id " +
																"from IShareAreaResult sar " +
																"where sar.shareAreaID='"+areaUID+"'))";
		this.runFormatHSql(delSinkResultHql);
		String delUserResultHql = "delete from IUserShareResult usr " +
				"where usr.areaResultID in(select sar.id " +
										"from IShareAreaResult sar " +
										"where sar.shareAreaID='"+areaUID+"')";
		this.runFormatHSql(delUserResultHql);
		String delAreaResultHql = "delete from IShareAreaResult sar " +
				"where sar.shareAreaID='"+areaUID+"'";
		this.runFormatHSql(delAreaResultHql);
		//删除分摊域所属系统用户、用户角色
		String delUserRoleHql = "delete from IUserRole ur " +
				"where ur.userUuid in(select u.id " +
									"from IUser u " +
									"where u.roomId in(select hr.id " +
													"from IHeatRoom hr " +
													"where hr.shareAreaID='"+areaUID+"'))";
		this.runFormatHSql(delUserRoleHql);
		String deleteUserHql = "delete from IUser u " +
				"where u.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.shareAreaID='"+areaUID+"')";
		this.runFormatHSql(deleteUserHql);
		//删除分摊域所属热用户
		String delRoomHql = "delete from IHeatRoom hr " +
				"where hr.shareAreaID='"+areaUID+"'";
		this.runFormatHSql(delRoomHql);
		//删除分摊域信息
		this.deleteEntityById(areaUID);
		return ResponseMsg.getInstance(true, "");
	}

	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}
	
}
